package com.yuelan.codelib.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.List;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

/**
 * 作者: peijiangping<BR>
 * 2013-1-6下午3:12:22<BR>
 * HttpConnent.java<BR>
 * 功能:网络请求类<BR>
 */
public class HttpConnent {
	public static final int TIMEOUT_VALUE = 10000;
	public static final int MAX_REHTTPTIME = 3;

	public static DefaultHttpClient getHttpClient() {
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams
				.setConnectionTimeout(httpParameters, TIMEOUT_VALUE);
		HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_VALUE);
		DefaultHttpClient defaultHttpClient = new DefaultHttpClient(
				httpParameters);
		return defaultHttpClient;
	}

	public static List<Cookie> getHttpCookie(String httpUrl) {
		List<Cookie> str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpPost request = new HttpPost(httpUrl);
			request.setHeader("Charset", "UTF-8");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			// request.setHeader("User-Agent", "DuoNiu");
			HttpContext context = new BasicHttpContext();
			CookieStore cookieStore = new BasicCookieStore();
			context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
			HttpResponse response = defaultHttpClient.execute(request, context);
			if (response.getStatusLine().getStatusCode() == 200) {
				EntityUtils.toString(response.getEntity(), "UTF-8");
				str = cookieStore.getCookies();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	public static String doHttpGet(String httpUrl, String cookies, int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpGet request = new HttpGet(httpUrl);
			request.setHeader("Charset", "UTF-8");
			if (TextUtil.notNull(cookies)) {
				request.setHeader("Cookie", cookies);
			}
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpGet(httpUrl, cookies, time);
			}
		}
		return str;
	}

	public static String doHttpGet(String httpUrl, int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpGet request = new HttpGet(httpUrl);
			request.setHeader("Charset", "UTF-8");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpGet(httpUrl, time);
			}
		}
		return str;
	}

	public static String doHttpDLGet(String httpUrl, String ip, int port,
			int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpGet request = new HttpGet(httpUrl);
			request.setHeader("Charset", "UTF-8");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			// request.setHeader("User-Agent", "DuoNiu");
			HttpHost proxy = new HttpHost(ip, port);
			defaultHttpClient.getParams().setParameter(
					ConnRoutePNames.DEFAULT_PROXY, proxy);
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpDLGet(httpUrl, ip, port, time);
			}
		}
		return str;
	}

	public static String doHttpPost(String httpUrl, String cookie, int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpPost request = new HttpPost(httpUrl);
			request.setHeader("Charset", "UTF-8");
			if (TextUtil.notNull(cookie)) {
				request.setHeader("Cookie", cookie);
			}
			// request.setHeader("User-Agent", "DuoNiu");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpPost(httpUrl, cookie, time);
			}
		}
		return str;
	}

	public static String doHttpPost(String httpUrl, int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpPost request = new HttpPost(httpUrl);
			request.setHeader("Charset", "UTF-8");
			// request.setHeader("User-Agent", "DuoNiu");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpPost(httpUrl, time);
			}
		}
		return str;
	}

	public static String doHttpPostString(String httpUrl, String xml, int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpPost request = new HttpPost(httpUrl);
			request.setHeader("Charset", "UTF-8");
			request.setHeader("User-Agent", "DuoNiu");
			// request.setHeader("Content-Type",
			// "application/x-www-form-urlencoded");
			request.setHeader("Content-Type", "text/xml");
			StringEntity entity = new StringEntity(xml);
			request.setEntity(entity);
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpPostString(httpUrl, xml, time);
			}
		}
		return str;
	}

	public static String doHttpPost(String httpUrl, List<NameValuePair> params,
			int time) {
		String str = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpPost request = new HttpPost(httpUrl);
			request.setHeader("Charset", "UTF-8");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			request.setHeader("User-Agent", "DuoNiu");
			if (params != null) {
				request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
			}
			HttpResponse response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				str = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (str == null) {
			time++;
			if (time < MAX_REHTTPTIME) {
				return doHttpPost(httpUrl, params, time);
			}
		}
		return str;
	}

	public static void setHttpRequestRetryHandler(
			DefaultHttpClient defaultHttpClient) {
		HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
			@Override
			public boolean retryRequest(IOException exception,
					int executionCount, HttpContext context) {
				// 设置恢复策略，在发生异常时候将自动重试N次
				if (executionCount >= 2) {
					// 如果超过最大重试次数，那么就不要继续了
					return false;
				}
				if (exception instanceof NoHttpResponseException) {
					// 如果服务器丢掉了连接，那么就重试
					return true;
				}
				if (exception instanceof SSLHandshakeException) {
					// 不要重试SSL握手异常
					return false;
				}
				if (exception instanceof ConnectException) {
					// Connection refused
					return false;
				}
				if (exception instanceof SSLException) {
					// SSL handshake exception
					return false;
				}
				if (exception instanceof InterruptedIOException) {
					// Timeout
					return true;
				}
				if (exception instanceof UnknownHostException) {
					// Unknown host
					return false;
				}
				HttpRequest request = (HttpRequest) context
						.getAttribute(ExecutionContext.HTTP_REQUEST);
				boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
				if (!idempotent) {
					// 如果请求被认为是幂等的，那么就重试
					return true;
				}
				return false;
			}
		};
		defaultHttpClient.setHttpRequestRetryHandler(myRetryHandler);
	}

	public static long getHttpFileSize(String url) {
		long size = 0;
		HttpResponse response_test = null;
		try {
			HttpClient hp = new DefaultHttpClient();
			HttpGet request_test = new HttpGet(url);
			response_test = hp.execute(request_test);
			size = response_test.getEntity().getContentLength();
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
		return size;
	}

	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		inStream.close();
		return outStream.toByteArray();
	}

	public static int download(String url, File file, int times) {
		int value = -1;
		HttpResponse response = null;
		InputStream is = null;
		FileOutputStream fos = null;
		try {
			DefaultHttpClient defaultHttpClient = getHttpClient();
			HttpGet request = new HttpGet(url);
			response = defaultHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == 200) {
				is = response.getEntity().getContent();
				if (is == null) {
					throw new RuntimeException("stream is null");
				}
				// 获取文件对象，开始往文件里面写内容
				fos = new FileOutputStream(file);
				byte buf[] = new byte[1024];
				do {
					int numread = is.read(buf);
					if (numread <= 0) {
						break;
					}
					fos.write(buf, 0, numread);
				} while (true);
				is.close();
				value = 1;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			value = -1;
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
					value = -1;
				}
				is = null;
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
					value = -1;
				}
				fos = null;
			}
		}
		if (value != 1) {
			// 重试次数1
			if (times < 1) {
				times = times + 1;
				download(url, file, times);
			}
		}
		return value;
	}
}